home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / gfx / conv / jpegV5Asrc.lha / jpeg-5a / jdpostct.c < prev    next >
C/C++ Source or Header  |  1994-07-05  |  9KB  |  276 lines

  1. /*
  2.  * jdpostct.c
  3.  *
  4.  * Copyright (C) 1994, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains the decompression postprocessing controller.
  9.  * This controller manages the upsampling, color conversion, and color
  10.  * quantization/reduction steps; specifically, it controls the buffering
  11.  * between upsample/color conversion and color quantization/reduction.
  12.  *
  13.  * If no color quantization/reduction is required, then this module has no
  14.  * work to do, and it just hands off to the upsample/color conversion code.
  15.  * An integrated upsample/convert/quantize process would replace this module
  16.  * entirely.
  17.  */
  18.  
  19. #define JPEG_INTERNALS
  20. #include "jinclude.h"
  21. #include "jpeglib.h"
  22.  
  23.  
  24. /* Private buffer controller object */
  25.  
  26. typedef struct {
  27.   struct jpeg_d_post_controller pub; /* public fields */
  28.  
  29.   /* Color quantization source buffer: this holds output data from
  30.    * the upsample/color conversion step to be passed to the quantizer.
  31.    * For two-pass color quantization, we need a full-image buffer;
  32.    * for one-pass operation, a strip buffer is sufficient.
  33.    */
  34.   jvirt_sarray_ptr whole_image;    /* virtual array, or NULL if one-pass */
  35.   JSAMPARRAY buffer;        /* strip buffer, or current strip of virtual */
  36.   JDIMENSION strip_height;    /* buffer size in rows */
  37.   /* for two-pass mode only: */
  38.   JDIMENSION starting_row;    /* row # of first row in current strip */
  39.   JDIMENSION next_row;        /* index of next row to fill/empty in strip */
  40. } my_post_controller;
  41.  
  42. typedef my_post_controller * my_post_ptr;
  43.  
  44.  
  45. /* Forward declarations */
  46. METHODDEF void post_process_1pass
  47.     JPP((j_decompress_ptr cinfo,
  48.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  49.          JDIMENSION in_row_groups_avail,
  50.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  51.          JDIMENSION out_rows_avail));
  52. #ifdef QUANT_2PASS_SUPPORTED
  53. METHODDEF void post_process_prepass
  54.     JPP((j_decompress_ptr cinfo,
  55.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  56.          JDIMENSION in_row_groups_avail,
  57.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  58.          JDIMENSION out_rows_avail));
  59. METHODDEF void post_process_2pass
  60.     JPP((j_decompress_ptr cinfo,
  61.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  62.          JDIMENSION in_row_groups_avail,
  63.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  64.          JDIMENSION out_rows_avail));
  65. #endif
  66.  
  67.  
  68. /*
  69.  * Initialize for a processing pass.
  70.  */
  71.  
  72. METHODDEF void
  73. start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
  74. {
  75.   my_post_ptr post = (my_post_ptr) cinfo->post;
  76.  
  77.   switch (pass_mode) {
  78.   case JBUF_PASS_THRU:
  79.     if (cinfo->quantize_colors) {
  80.       /* Single-pass processing with color quantization. */
  81.       post->pub.post_process_data = post_process_1pass;
  82.     } else {
  83.       /* For single-pass processing without color quantization,
  84.        * I have no work to do; just call the upsampler directly.
  85.        */
  86.       post->pub.post_process_data = cinfo->upsample->upsample;
  87.     }
  88.     break;
  89. #ifdef QUANT_2PASS_SUPPORTED
  90.   case JBUF_SAVE_AND_PASS:
  91.     /* First pass of 2-pass quantization */
  92.     if (post->whole_image == NULL)
  93.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  94.     post->pub.post_process_data = post_process_prepass;
  95.     break;
  96.   case JBUF_CRANK_DEST:
  97.     /* Second pass of 2-pass quantization */
  98.     if (post->whole_image == NULL)
  99.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  100.     post->pub.post_process_data = post_process_2pass;
  101.     break;
  102. #endif /* QUANT_2PASS_SUPPORTED */
  103.   default:
  104.     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  105.     break;
  106.   }
  107.   post->starting_row = post->next_row = 0;
  108. }
  109.  
  110.  
  111. /*
  112.  * Process some data in the one-pass (strip buffer) case.
  113.  * This is used for color precision reduction as well as one-pass quantization.
  114.  */
  115.  
  116. METHODDEF void
  117. post_process_1pass (j_decompress_ptr cinfo,
  118.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  119.             JDIMENSION in_row_groups_avail,
  120.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  121.             JDIMENSION out_rows_avail)
  122. {
  123.   my_post_ptr post = (my_post_ptr) cinfo->post;
  124.   JDIMENSION num_rows, max_rows;
  125.  
  126.   /* Fill the buffer, but not more than what we can dump out in one go. */
  127.   /* Note we rely on the upsampler to detect bottom of image. */
  128.   max_rows = out_rows_avail - *out_row_ctr;
  129.   if (max_rows > post->strip_height)
  130.     max_rows = post->strip_height;
  131.   num_rows = 0;
  132.   (*cinfo->upsample->upsample) (cinfo,
  133.         input_buf, in_row_group_ctr, in_row_groups_avail,
  134.         post->buffer, &num_rows, max_rows);
  135.   /* Quantize and emit data. */
  136.   (*cinfo->cquantize->color_quantize) (cinfo,
  137.         post->buffer, output_buf + *out_row_ctr, (int) num_rows);
  138.   *out_row_ctr += num_rows;
  139. }
  140.  
  141.  
  142. #ifdef QUANT_2PASS_SUPPORTED
  143.  
  144. /*
  145.  * Process some data in the first pass of 2-pass quantization.
  146.  */
  147.  
  148. METHODDEF void
  149. post_process_prepass (j_decompress_ptr cinfo,
  150.               JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  151.               JDIMENSION in_row_groups_avail,
  152.               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  153.               JDIMENSION out_rows_avail)
  154. {
  155.   my_post_ptr post = (my_post_ptr) cinfo->post;
  156.   JDIMENSION old_next_row, num_rows;
  157.  
  158.   /* Reposition virtual buffer if at start of strip. */
  159.   if (post->next_row == 0) {
  160.     post->buffer = (*cinfo->mem->access_virt_sarray)
  161.     ((j_common_ptr) cinfo, post->whole_image, post->starting_row, TRUE);
  162.   }
  163.  
  164.   /* Upsample some data (up to a strip height's worth). */
  165.   old_next_row = post->next_row;
  166.   (*cinfo->upsample->upsample) (cinfo,
  167.         input_buf, in_row_group_ctr, in_row_groups_avail,
  168.         post->buffer, &post->next_row, post->strip_height);
  169.  
  170.   /* Allow quantizer to scan new data.  No data is emitted, */
  171.   /* but we advance out_row_ctr so outer loop can tell when we're done. */
  172.   if (post->next_row > old_next_row) {
  173.     num_rows = post->next_row - old_next_row;
  174.     (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
  175.                      (JSAMPARRAY) NULL, (int) num_rows);
  176.     *out_row_ctr += num_rows;
  177.   }
  178.  
  179.   /* Advance if we filled the strip. */
  180.   if (post->next_row >= post->strip_height) {
  181.     post->starting_row += post->strip_height;
  182.     post->next_row = 0;
  183.   }
  184. }
  185.  
  186.  
  187. /*
  188.  * Process some data in the second pass of 2-pass quantization.
  189.  */
  190.  
  191. METHODDEF void
  192. post_process_2pass (j_decompress_ptr cinfo,
  193.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  194.             JDIMENSION in_row_groups_avail,
  195.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  196.             JDIMENSION out_rows_avail)
  197. {
  198.   my_post_ptr post = (my_post_ptr) cinfo->post;
  199.   JDIMENSION num_rows, max_rows;
  200.  
  201.   /* Reposition virtual buffer if at start of strip. */
  202.   if (post->next_row == 0) {
  203.     post->buffer = (*cinfo->mem->access_virt_sarray)
  204.     ((j_common_ptr) cinfo, post->whole_image, post->starting_row, FALSE);
  205.   }
  206.  
  207.   /* Determine number of rows to emit. */
  208.   num_rows = post->strip_height - post->next_row; /* available in strip */
  209.   max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
  210.   if (num_rows > max_rows)
  211.     num_rows = max_rows;
  212.   /* We have to check bottom of image here, can't depend on upsampler. */
  213.   max_rows = cinfo->output_height - post->starting_row;
  214.   if (num_rows > max_rows)
  215.     num_rows = max_rows;
  216.  
  217.   /* Quantize and emit data. */
  218.   (*cinfo->cquantize->color_quantize) (cinfo,
  219.         post->buffer + post->next_row, output_buf + *out_row_ctr,
  220.         (int) num_rows);
  221.   *out_row_ctr += num_rows;
  222.  
  223.   /* Advance if we filled the strip. */
  224.   post->next_row += num_rows;
  225.   if (post->next_row >= post->strip_height) {
  226.     post->starting_row += post->strip_height;
  227.     post->next_row = 0;
  228.   }
  229. }
  230.  
  231. #endif /* QUANT_2PASS_SUPPORTED */
  232.  
  233.  
  234. /*
  235.  * Initialize postprocessing controller.
  236.  */
  237.  
  238. GLOBAL void
  239. jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
  240. {
  241.   my_post_ptr post;
  242.  
  243.   post = (my_post_ptr)
  244.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  245.                 SIZEOF(my_post_controller));
  246.   cinfo->post = (struct jpeg_d_post_controller *) post;
  247.   post->pub.start_pass = start_pass_dpost;
  248.   post->whole_image = NULL;    /* flag for no virtual arrays */
  249.  
  250.   /* Create the quantization buffer, if needed */
  251.   if (cinfo->quantize_colors) {
  252.     /* The buffer strip height is max_v_samp_factor, which is typically
  253.      * an efficient number of rows for upsampling to return.
  254.      * (In the presence of output rescaling, we might want to be smarter?)
  255.      */
  256.     post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
  257.     if (need_full_buffer) {
  258.       /* Two-pass color quantization: need full-image storage. */
  259. #ifdef QUANT_2PASS_SUPPORTED
  260.       post->whole_image = (*cinfo->mem->request_virt_sarray)
  261.     ((j_common_ptr) cinfo, JPOOL_IMAGE,
  262.      cinfo->output_width * cinfo->out_color_components,
  263.      cinfo->output_height, post->strip_height);
  264. #else
  265.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  266. #endif /* QUANT_2PASS_SUPPORTED */
  267.     } else {
  268.       /* One-pass color quantization: just make a strip buffer. */
  269.       post->buffer = (*cinfo->mem->alloc_sarray)
  270.     ((j_common_ptr) cinfo, JPOOL_IMAGE,
  271.      cinfo->output_width * cinfo->out_color_components,
  272.      post->strip_height);
  273.     }
  274.   }
  275. }
  276.